﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KMS.Core
{
    using System.Dynamic;

    public partial class ServiceBase<T>
    {
        public IEnumerable<T> GetModelList(Criteria filter)
        {
            IEnumerable<T> result = null;
            QueryExcute(
                db =>
                {
                    var query = new Query<T>();
                    query.Filter = filter;
                    result = db.QueryWith(query);
                }
             );
            return result;
        }
 
        public T GetModel(dynamic key)
        {
            T result = default(T);
            var query = new Query<T>();

            var keyColumns = typeof(T).GetSelectClause().Where(x => x.Identity || x.IsPrimaryKey).ToList();
            if (!keyColumns.Any())
            {
                throw new ArgumentException("Entity must have at least one [Key] property");
            }
            if (keyColumns.Count() > 1)
            {
                throw new Exception("Get<T> only supports an entity with a single [Key] property");
            }
            query.Filter = new IdCriteria(key, keyColumns.First().Name);
            query.SelectTopClause = " TOP 1 ";

            QueryExcute(
                db =>
                { 
                    result = db.QueryWith(query).SingleOrDefault();
                }
             );
            return result;
        }
        public T GetModel(Criteria filter)
        {
            T result = default(T);
            QueryExcute(
                db =>
                {
                    var query = new Query<T>();
                    
                    query.Filter = filter;
                    query.SelectTopClause = " TOP 1 ";
                    result = db.QueryWith(query).SingleOrDefault();
                }
             );
            return result;
        }

        public IEnumerable<object> GetList(QueryImp query)
        {
            IEnumerable<object> result = null;
            QueryExcute(
                db =>
                { result = db.QueryWith(query); }
             );
            return result;
        }
        public IEnumerable<TModel> GetList<TModel>(Query<TModel> query)
        {
            IEnumerable<TModel> result = null;
            QueryExcute(
                db =>
                { result = db.QueryWith(query); }
             );
            return result;
        }
        public Tresult ScalarWith<Tresult>(Query<Tresult> query)
        {
            Tresult result = default(Tresult);
            QueryExcute(
                db =>
                {
                    result = db.ScalarWith<Tresult>(query);
                }
             );
            return result;
        }
    }
}
